﻿using System;
using System.Runtime.InteropServices;

namespace Demo
{
    class Program
    {
        /***
         * 满足以下条件时，GC才会工作：
             1. 系统具有较低的物理内存；
             2. 由托管堆上已分配的对象使用的内存超出了可接受的范围；
             3. 手动调用GC.Collect方法，但几乎所有的情况下，我们都不必调用，因为垃圾回收器会自动调用它，但在上面的例子中，
                为了体验一下不及时回收垃圾带来的危害，所以手动调用了GC.Collect，大家也可以仔细体会一下运行这个方法带来的不同。
            假如 我们用FileStream 打开一个文件，正在读取， 没有关闭释放，  在开启一个线程读取，就会报错资源在使用中， 如果用完及时关闭，别的线程访问就不会报错
         GC还有个“代”的概念，一共分3代：0代、1代、2代。而这三代，相当于是三个队列容器，第0代包含的是一些短期生存的对象，上面的例子fs就是个短期对象，当方法执行完后，fs就被丢到了GC的第0代，但不进行垃圾回收，只有当第0代满了的时候，系统认为此时满足了低内存的条件，才会触发垃圾回收事件。所以我们永远不知道fs什么时候被回收掉，在回收之前，它实际上已经没有用处了，但始终占着系统资源不放(占着茅坑不拉屎)，这对系统来说是种极大的浪费，而且这种浪费还会干扰整个系统的运行，比如我们的例子，由于它始终占着资源，就导致了我们不能再对文件进行访问了。
         不及时释放资源还会带来另外的一个问题，虽然之前我们说实现IDisposable接口的类，GC可以自动帮我们释放，但这个过程被延长了，因为它不是在一次回收中完成所有的清理工作，即使GC自动帮我们释放了，那也是先调用FileStream的终结器，在下一次的垃圾回收时才会真正的被释放。
         了解到危害后，我们在打码过程中，如果我们明知道它应该被using起来时，一定要using起来

        静态成员一般都是一个根， 不受gc 的管理  将某某设置为null  根据就不会加快 gc 处理，编译器也不会 将改代码编译进去，静态字段不一样  是可以设置为null 的 ，内存占用太大就可以
         * 
         * ***/


        static void Main(string[] args)
        {
            






        }
    }

    public class A: IDisposable
    {

        /// <summary>
        /// 模拟一个非托管资源
        /// </summary>
        private IntPtr NativeResource { get; set; } = Marshal.AllocHGlobal(100);
        /// <summary>
        /// 模拟一个托管资源
        /// </summary>
        public Random ManagedResource { get; set; } = new Random();


        public int Id { get; set; }

        public string Name { get; set; }

        public string Age { get; set; }

        private bool disposed;

        ~A()
        {
            Dispose(false);
        }
        public void Dispose()
        {
            //必须为true
            Dispose(true);
            //通知垃圾回收器不再调用终结器
            GC.SuppressFinalize(this);
        }

        public virtual void Dispose(bool disposing)
        {
            if (disposed)
            {
                return;
            }
            //清理托管资源
            if (disposing)
            {
                if (ManagedResource != null)
                {
                    ManagedResource = null;
                }
            }
            //清理非托管资源
            if (NativeResource != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(NativeResource);
                NativeResource = IntPtr.Zero;
            }
            //告诉自己已经被释放
            disposed = true;
        }

    }



}
